package service

import (
	"fmt"
	"singo/model"
	"singo/serializer"
	"sort"
	"strconv"
)

// PerformanceRankService 待审核已审核管理列表服务
type PerformanceRankService struct {
	Limit     int    `form:"pageSize" json:"pageSize"`
	Start     int    `form:"pageNo" json:"pageNo"`
	StartTime string `form:"start_time" json:"start_time"`
	EndTime   string `form:"end_time" json:"end_time"`
}

type UserWithPerformanceArray []model.UserWithPerformance

func (s UserWithPerformanceArray) Len() int           { return len(s) }
func (s UserWithPerformanceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s UserWithPerformanceArray) Less(i, j int) bool { return s[i].Score > s[j].Score } // 从大到小排序

// PerformanceRank 待审核已审核管理列表
func (service *PerformanceRankService) PerformanceRank() serializer.Response {
	user_with_performances := []model.UserWithPerformance{}
	users := []model.User{}
	total := 0

	if service.Limit == 0 {
		service.Limit = 99 // 涉及排序，表里没有这个字段，所以先用这个方式
	} else {
		service.Limit = 99
	}

	if err := model.DB.Model(&users).Count(&total).Error; err != nil {
		return serializer.Response{
			Status: 50000,
			Msg:    "数据库连接错误",
			Error:  err.Error(),
		}
	}

	if err := model.DB.Limit(service.Limit).Offset((service.Start - 1) * service.Limit).Find(&users).Error; err != nil {
		return serializer.Response{
			Status: 50000,
			Msg:    "数据库连接错误",
			Error:  err.Error(),
		}
	}

	for _, item := range users {
		tasks := []model.Task{}
		weight_total := 0.0
		score := 0.0
		score_total := 0.0

		if err := model.DB.Where("deadline_at BETWEEN ? AND ?", service.StartTime, service.EndTime).Where("execute_by LIKE ?", "%"+item.UID+"%").Find(&tasks).Error; err != nil {
			return serializer.Response{
				Status: 50000,
				Msg:    "数据库连接错误",
				Error:  err.Error(),
			}
		}

		for _, task := range tasks {
			weight_total += task.Weight
		}
		for _, task := range tasks {
			score += task.Score * (task.Weight / weight_total) * 100
			score_total, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", score), 64)
		}

		user_with_performance := model.UserWithPerformance{
			UID:             item.UID,
			Nickname:        item.Nickname,
			OrganizationUID: item.OrganizationUID,
			Score:           score_total,
		}
		user_with_performances = append(user_with_performances, user_with_performance)
	}
	sort.Sort(UserWithPerformanceArray(user_with_performances))

	return serializer.BuildListResponse(serializer.BuildUsersWithPerformance(user_with_performances), uint(total))
}
